package com.cx.gateway.listener;

import com.cx.gateway.menu.MenuService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;

import javax.annotation.Resource;

@Slf4j
@Configuration
public class SubListenerConfig {

    @Resource
    private MenuService menuService;

    //消息监听
    @Bean
    MessageListenerAdapter messageListener() {
        return new MessageListenerAdapter(new MessageListener() {
            @Override
            public void onMessage(Message message, byte[] bytes) {
                log.info(message.toString());
                menuService.updateMenuInfo();
            }
        });
    }
    //消息监听容器
    /*
    RedisMessageListenerContainer
    其实现了InitializingBean, DisposableBean, BeanNameAware, SmartLifecycle几个接口
    InitializingBean：主要实现afterPropertiesSet方法，来定义spring设置完properties后进行的处理，在spring init这个bean时候会被调用
    DisposableBean：实现destroy方法，在spring销毁bean时会调用
    BeanNameAware：实现setBeanName方法来为bean进行取名，在RedisMessageListenerContainer中该name被用于内部线程的线程名
    SmartLifecycle：spring的bean生命周期类，spring会调用start，stop等操作来完成RedisMessageListenerContainer类的启动
     */
    @Bean
    RedisMessageListenerContainer redisContainer(RedisConnectionFactory factory) {
        final RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(factory);
        container.addMessageListener(messageListener(), new ChannelTopic( "topic:menu" ));
        return container;
    }
}
